package com.zdxlz.fcmp.common.security;

import com.zdxlz.fcmp.common.security.filter.IctHmacAuthenticationFilter;
import com.zdxlz.fcmp.common.security.filter.JwtAuthenticationTokenFilter;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
import org.springframework.security.config.annotation.web.configurers.HeadersConfigurer;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.access.AccessDeniedHandler;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;
import org.springframework.security.web.util.matcher.RequestMatcher;
import org.springframework.web.cors.CorsConfigurationSource;

/**
 * @className SecurityConfig
 * @description
 * @author: aman
 * @date 2025/1/30 19:20
 */
@Slf4j
@Configuration
@EnableWebSecurity
@AllArgsConstructor
public class SecurityConfig {

    private final AuthenticationManager authenticationManager;
    private final IctHmacAuthenticationFilter ictHmacAuthenticationFilter;
    private final JwtAuthenticationTokenFilter jwtAuthenticationTokenFilter;
    private final CorsConfigurationSource corsConfigurationSource;
    private final AccessDeniedHandler customAccessDeniedHandler;
    private final AuthenticationEntryPoint customAuthenticationEntryPoint;
    @Qualifier("excludeMatcher")
    private final RequestMatcher excludeMatcher;


    @Bean
    protected SecurityFilterChain filterChain(HttpSecurity http) throws Exception {

        http
                .formLogin(AbstractHttpConfigurer::disable)
                // 由于使用的是JWT，我们这里不需要csrf
                .csrf(AbstractHttpConfigurer::disable)
                // 基于token，所以不需要session
                .sessionManagement(AbstractHttpConfigurer::disable)
                .authorizeHttpRequests(authorize -> authorize
                        .requestMatchers(excludeMatcher).permitAll()
                        .anyRequest().authenticated());

        // 然后，添加HMAC过滤器
        http.addFilterBefore(ictHmacAuthenticationFilter, BasicAuthenticationFilter.class);
        // 在【UsernamePasswordAuthenticationFilter】之前添加JWT过滤器
        http.addFilterBefore(jwtAuthenticationTokenFilter, UsernamePasswordAuthenticationFilter.class);
        // 禁用缓存
        http.headers(headers -> headers.cacheControl(HeadersConfigurer.CacheControlConfig::disable));

        // 添加自定义未授权和未登录结果返回
        http.exceptionHandling(exceptionHandling -> exceptionHandling
                .accessDeniedHandler(customAccessDeniedHandler)
                .authenticationEntryPoint(customAuthenticationEntryPoint)
        );

        // 注入authenticationManager
        http.authenticationManager(authenticationManager);

        // 允许跨域请求
        http.cors(cors -> cors.configurationSource(corsConfigurationSource));
        return http.build();
    }

}
